﻿using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using System.Windows.Forms.Design;

namespace AutoUI
{
    public class FlowBarProDesigner : ControlDesigner
    {
        #region Fields

        private DesignerVerbCollection _verbs;

        #endregion Fields

        #region Constructors

        public FlowBarProDesigner()
        {
            //this.Control.SetDoubleBuffered();
        }

        #endregion Constructors

        #region Properties

        /// <summary>
        /// 光标在控件里面
        /// </summary>
        public bool Designing { get; set; } = true;

        public override SelectionRules SelectionRules
        {
            get
            {
                SelectionRules sr = base.SelectionRules;
                //if (((高级流动条)Control).DesignerMove)
                //{
                //    sr |= SelectionRules.Moveable;
                //}
                //else
                //{
                //    sr &= ~SelectionRules.Moveable;
                //}
                return sr;
            }
        }

        //public override IList SnapLines
        //{
        //    get
        //    {
        //        IList lines = new ArrayList();
        //        高级流动条 ab = (高级流动条)this.Control;

        //        //  var con = (int)realpoints.First().X;
        //        //左对齐线
        //        //SnapLine left1 = new SnapLine(SnapLineType.Left, 1);
        //        //SnapLine left2 = new SnapLine(SnapLineType.Right, 1);
        //        ////右对齐线
        //        //SnapLine left3 = new SnapLine(SnapLineType.Left, Control.Width - 1);
        //        //SnapLine left4 = new SnapLine(SnapLineType.Right, Control.Width - 1);

        //        //SnapLine v1ine1 = new SnapLine(SnapLineType.Top, 1);
        //        //SnapLine v1ine2 = new SnapLine(SnapLineType.Bottom, 1);

        //        //SnapLine v1ine3 = new SnapLine(SnapLineType.Top, Control.Height - 1);
        //        //SnapLine v1ine4 = new SnapLine(SnapLineType.Bottom, Control.Height - 1);

        //        SnapLine l1 = new SnapLine(SnapLineType.Left, (int)ab.FlowBars.First().RealPoints.First().X);
        //        //SnapLine l2 = new SnapLine(SnapLineType.Right, 0);
        //        ////右对齐线
        //        //SnapLine l3 = new SnapLine(SnapLineType.Left, Control.Width - 0);
        //        //SnapLine l4 = new SnapLine(SnapLineType.Right, Control.Width - 0);

        //        //SnapLine l5 = new SnapLine(SnapLineType.Top, 0);
        //        //SnapLine l6 = new SnapLine(SnapLineType.Bottom, 0);

        //        //SnapLine l7 = new SnapLine(SnapLineType.Top, Control.Height - 0);
        //        //SnapLine l8 = new SnapLine(SnapLineType.Bottom, Control.Height - 0);
        //        // SnapLine l9 = new SnapLine(SnapLineType.Left, con);

        //        lines.Add(l1);
        //        //lines.Add(l2);
        //        //lines.Add(l3);
        //        //lines.Add(l4);
        //        //lines.Add(l5);
        //        //lines.Add(l6);
        //        //lines.Add(l7);
        //        //lines.Add(l8);

        //        //lines.Add(left1);
        //        //lines.Add(left2);
        //        //lines.Add(left3);
        //        //lines.Add(left4);
        //        //lines.Add(v1ine1);
        //        //lines.Add(v1ine2);
        //        //lines.Add(v1ine3);
        //        //lines.Add(v1ine4);

        //        //lines.Add(l1);
        //        //lines.Add(l2);
        //        //lines.Add(l3);
        //        //lines.Add(l4);
        //        //lines.Add(l5);
        //        //lines.Add(l6);
        //        //lines.Add(l7);
        //        //lines.Add(l8);
        //        //   lines.Add(l9);

        //        return lines;
        //    }
        //}

        /// <summary>
        /// 添加右键菜单
        /// </summary>
        public override DesignerVerbCollection Verbs
        {
            get
            {
                if (_verbs == null)
                {
                    _verbs = new DesignerVerbCollection();
                    _verbs.Add(new DesignerVerb("增加流动条", new EventHandler(StartDesigner)));
                    _verbs.Add(new DesignerVerb("结束设计", new EventHandler(StopDesigner)));

                    _verbs.Add(new DesignerVerb("删除正在编辑的流动条", new EventHandler(DeleteFlowBar)));
                    _verbs.Add(new DesignerVerb("修改正在编辑的流动条", new EventHandler(AddPoint)));
                    //_verbs.Add(new DesignerVerb("(从新设计)删除所有点", (s, e) =>
                    //{
                    //    ps = new List<System.Drawing.PointF>();
                    //}));
                }
                return _verbs;
            }
        }

        #endregion Properties

        #region Methods

        protected override void OnMouseDragBegin(int x, int y)
        {
            // 高级流动条_ ab = (高级流动条_)this.Control;
            //  System.Drawing.Point point = ab.PointToClient(Control.MousePosition);
            base.OnMouseDragBegin(x, y);
        }

        protected override void OnMouseDragEnd(bool cancel)
        {
            // 高级流动条_ ab = (高级流动条_)this.Control;
            //  System.Drawing.Point point = ab.PointToClient(Control.MousePosition);
            base.OnMouseDragEnd(cancel);
        }

        protected override void OnMouseDragMove(int x, int y)
        {
            System.Drawing.Point mp = new System.Drawing.Point(x, y);
            高级流动条_ ab = (高级流动条_)this.Control;
            //base.OnMouseDragMove(x, y);

            System.Drawing.Point point = ab.PointToClient(Control.MousePosition);
            if (ab.DesignStatus == EnumDesignStatus.Change && ab.Indexline != -1 && ab.Indexpoint != -1)
            {
                var xx = point.X / (float)Control.Width;
                var yy = point.Y / (float)Control.Height;
                ab.FlowBars_[ab.Indexline].Points[ab.Indexpoint] = new PointF(xx, yy);
                ab.FlowBars_[ab.Indexline].RealPoints[ab.Indexpoint] = point;
            }
            else
            {
                base.OnMouseDragMove(x, y);
            }
            ab.Invalidate();
        }

        protected override void OnMouseEnter()
        {
            base.OnMouseEnter();
            高级流动条_ ab = (高级流动条_)this.Control;
            System.Drawing.Point point = ab.PointToClient(Control.MousePosition);
            Designing = true;
            ab.Invalidate();
        }

        protected override void OnMouseLeave()
        {
            base.OnMouseLeave();
            高级流动条_ ab = (高级流动条_)this.Control;
            System.Drawing.Point point = ab.PointToClient(Control.MousePosition);
            Designing = false;
            ab.Invalidate();
        }

        protected override void OnPaintAdornments(PaintEventArgs pe)
        {
            base.OnPaintAdornments(pe);
            if (Designing)
            {
                高级流动条_ ab = (高级流动条_)this.Control;
                System.Drawing.Point point = ab.PointToClient(Control.MousePosition);
                var g = pe.Graphics;
                using (StringFormat sf = new StringFormat())
                {
                    sf.Alignment = StringAlignment.Center;
                    sf.LineAlignment = StringAlignment.Center;

                    foreach (var c in ab.FlowBars_)
                    {
                        int i = 0;
                        //   var  c.FlowFluidColor.ChangeColor(0.5f);
                        foreach (var item in c.RealPoints)
                        {
                            CircleF cc = new CircleF(item, 20);
                            g.DrawEllipse(Pens.LightBlue, cc);
                            g.DrawString(i.ToString(), ab.Font, Brushes.Black, cc, sf);
                            i++;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 在每次需要设置光标时接收调用
        /// </summary>
        protected override void OnSetCursor()
        {
            base.OnSetCursor();

            if (Cursor.Current != Cursors.Arrow)
            {
                Cursor.Current = Cursors.Arrow;
            }
        }

        /// <summary>
        /// 处理 Windows 消息，并可以选择将其路由到控件。
        /// </summary>
        /// <param name="m"></param>
        protected override void WndProc(ref Message m)
        {
            // MessageBox.Show(m.Msg.ToString());
            if (m.Msg == Win32.WM_LBUTTONDOWN)
            {
                this.OnMouseLeftDown();
            }
            else if (m.Msg == Win32.WM_LBUTTONUP)
            {
                this.OnMouseLeftUp();
            }
            else if (m.Msg == Win32.WM_RBUTTONUP)
            {
                this.OnMouseRightUp();
            }
            else if (m.Msg == Win32.WM_MOUSEMOVE)
            {
                this.OnMouseMove();
                高级流动条_ ab = (高级流动条_)this.Control;
            }

            base.WndProc(ref m);
        }

        /// <summary>
        /// 为正在编辑的流动条增加点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void AddPoint(object sender, EventArgs e)
        {
            高级流动条_ ab = (高级流动条_)this.Control;
            System.Drawing.Point point = ab.PointToClient(Control.MousePosition);
            if (ab.FlowBars_.Count > ab.Indexline && ab.FlowBars_.Count > 0 && ab.Indexline >= 0)
            {
                ab.DesignStatus = EnumDesignStatus.Designing;
            }
        }

        /// <summary>
        /// 删除选中的流动条
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DeleteFlowBar(object sender, EventArgs e)
        {
            高级流动条_ ab = (高级流动条_)this.Control;
            System.Drawing.Point point = ab.PointToClient(Control.MousePosition);
            if (ab.FlowBars_.Count > ab.Indexline && ab.FlowBars_.Count > 0 && ab.Indexline >= 0)
            {
                ab.FlowBars_.RemoveAt(ab.Indexline);
            }

            ab.Invalidate();
        }

        /// <summary>
        /// 获取正在设计的控件实例的某一个属性
        /// </summary>
        /// <param name="propName"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentException"></exception>
        private PropertyDescriptor GetPropertyByName(String propName)
        {
            PropertyDescriptor prop;
            prop = TypeDescriptor.GetProperties(Control)[propName];
            if (null == prop)
                throw new ArgumentException("组件未定义该属性。", propName);
            else
                return prop;
        }

        private void OnMouseLeftDown()
        {
            高级流动条_ ab = (高级流动条_)this.Control;
            System.Drawing.Point point = ab.PointToClient(Control.MousePosition);
            if (ab.DesignStatus == EnumDesignStatus.Designing && ab.Indexline >= 0 && ab.FlowBars_.Count > ab.Indexline)
            {
                var x = point.X / (float)Control.Width;
                var y = point.Y / (float)Control.Height;
                ab.FlowBars_[ab.Indexline].Points.Add(new System.Drawing.PointF(x, y));
            }
            else
            {
                if (ab.Indexline >= 0 && ab.FlowBars_.Count > ab.Indexline)
                {
                    for (int i = 0; i < ab.FlowBars_.Count; i++)
                    {
                        for (int j = 0; j < ab.FlowBars_[i].RealPoints.Count; j++)
                        {
                            CircleF c = new CircleF(ab.FlowBars_[i].RealPoints[j], ab.FlowBars_[i].FlowBarHeight);
                            if (c.Contains(point))
                            {
                                ab.Indexline = i;
                                ab.Indexpoint = j;
                                ab.DesignStatus = EnumDesignStatus.Change;
                                GetPropertyByName("Indexline").SetValue(ab, i);
                                GetPropertyByName("Indexpoint").SetValue(ab, j);
                                break;
                            }
                        }
                    }
                }
            }

            ab.Invalidate();
        }

        private void OnMouseLeftUp()
        {
            高级流动条_ ab = (高级流动条_)this.Control;
            System.Drawing.Point point = ab.PointToClient(Control.MousePosition);
            if (ab.DesignStatus != EnumDesignStatus.Designing)
            {
                ab.DesignStatus = EnumDesignStatus.Designed;
            }
        }

        private void OnMouseMove()
        {
            高级流动条_ ab = (高级流动条_)this.Control;
            System.Drawing.Point point = ab.PointToClient(Control.MousePosition);
            if (ab.DesignStatus == EnumDesignStatus.Designing)
            {
                ab.Invalidate();
            }
        }

        private void OnMouseRightUp()
        {
        }

        /// <summary>
        /// 开始设计
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void StartDesigner(object sender, EventArgs e)
        {
            高级流动条_ ab = (高级流动条_)this.Control;
            if (ab.FlowBars_.Count == 0)//一条都没有
            {
                ab.FlowBars_.Add(new FlowBar());
                GetPropertyByName("Indexline").SetValue(ab, 0);
                // ab.Indexline = 0;
            }
            else
            {
                if (ab.FlowBars_.Last().Points.Count > 1)//最后一条有两个点以上的点了
                {
                    ab.FlowBars_.Add(new FlowBar());
                    var index = ab.FlowBars_.Count - 1;
                    GetPropertyByName("Indexline").SetValue(ab, index);
                }
                else
                {
                    var index = ab.FlowBars_.Count - 1;
                    GetPropertyByName("Indexline").SetValue(ab, index);
                }
            }
            ab.DesignStatus = EnumDesignStatus.Designing;
        }

        /// <summary>
        /// 停止设计
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void StopDesigner(object sender, EventArgs e)
        {
            高级流动条_ ab = (高级流动条_)this.Control;
            ab.DesignStatus = EnumDesignStatus.Designed;
            ab.Invalidate();
            //GetPropertyByName("PS").SetValue(ab, pss);//将比例点赋值给正在被设计的控件
        }

        #endregion Methods
    }
}